package com.atguigu.day2;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @auther zzyy
 * @create 2024-08-06 8:34
 * 线程间定制化调用通信
 * <p>
 * * 多线程之间按顺序调用，实现A->B->C
 * * 三个线程启动，要求如下：
 * *
 * * AA打印5次，BB打印10次，CC打印15次
 * * 接着
 * * AA打印5次，BB打印10次，CC打印15次
 * * ......来10轮
 */

/**
 * 使用【condition】和【标志位】来做线程间的定制通讯
 */
class PrintOut {
    //先定义一个标志位 A 0 | B 1 | C 2
    int flag = 0;

    //创建一个Lock锁
    private Lock lock = new ReentrantLock();
    //使用Condition实现线程通信
    private Condition condition1 = lock.newCondition();
    private Condition condition2 = lock.newCondition();
    private Condition condition3 = lock.newCondition();

    public void method1() {
        lock.lock();
        try {
            //先判断
            if (flag != 0) {
                try {
                    condition1.await();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            //干活
            for (int i = 0; i < 5; i++) {
                System.out.println("A");
            }
            //通知，改标志位再通知具体的线程
            flag = 1;
            condition2.signal();
        } finally {
            lock.unlock();
        }

    }

    public void method2() {
        lock.lock();
        try {
            //判断标志位是否是1
            if (flag != 1) {
                try {
                    condition2.await();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            //干活
            for (int i = 0; i < 10; i++) {
                System.out.println("B");
            }
            //通知，改标志位，再通知具体的线程
            flag = 2;
            condition3.signal();
        } finally {
            lock.unlock();
        }
    }

    public void method3() {
        lock.lock();
        try {
            //判断
            if (flag != 2) {
                try {
                    condition3.await();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            //干活
            for (int i = 0; i < 15; i++) {
                System.out.println("CC");
            }
            //通知，改标志位
            flag = 0;
            condition1.signal();
        } finally {
            lock.unlock();
        }
    }
}

public class ThreadOrderAccess {
    public static void main(String[] args) {
        PrintOut printOut = new PrintOut();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                printOut.method1();
            }
        }, "线程1").start();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                printOut.method2();
            }
        }, "线程2").start();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                printOut.method3();
            }
        }, "线程3").start();
    }

}
